容易得到$$\frac{\partial{L}}{\partial{y_k}} = y_k - t_k$$
因为有$$net_k = \sum_x W_{x, k}\cdot y_x$$ 所以$$\frac{\partial{net_k}}{\partial{W_{j,k}}} = y_j$$
综上可以得到 $$\frac{\partial{L}}{\partial{W_{j,k}}} = (y_k - t_k)f^{'}(net_k)y_j$$
那么k号输出神经元隐含层到输出层权重参数的梯度为 $$\Delta{W_k} = (y_k - t_k)f^{'}(net_k)Y_{hidden}$$
注意 这里约定$W_k$和$Y_{hidden}$都是行向量。
这里有个问题,如果有多个输出怎么办?每个输出都会更新上一层的权重,难道取平均?不对,每个输出神经元对应的都是自己的权重,更新的也只是自己的。 那么隐含层到输出层所有的权重的梯度为(这里没办法编程矩阵运算,先放着吧)
同隐含层的关系有 $$\frac{\partial{net_j}}{\partial{W_{i,j}}} = y_i$$
这里求导时注意把损失函数展开,因为一个隐含层的神经元对应着多个输出层的神经元。 $$\begin{eqnarray} \frac{\partial{L}}{\partial{y_j}} &=& \frac{\partial}{\partial{y_j}}\left[ \frac{1}{2}\sum_k (y_k - t_k)^2\right]\\ &=&\sum_k (y_k - t_k)\frac{\partial{y_k}}{\partial{y_j}}\\ &=&\sum_k (y_k - t_k)f^{'}(net_k)W_{j,k}\\ \end{eqnarray}$$
综上,可以得到$$\frac{\partial{L}}{\partial{W_{i,j}}} = f^{'}(net_j) y_i \sum_k (y_k - t_k)f^{'}(net_k)W_{j,k}$$
那么j号神经元参数的梯度为$$\Delta W_j = Y_{input}f^{'}(net_j) \sum_k (y_k - t_k)f^{'}(net_k)(W_{j,k})$$
针对某个参数$W_{x, y}$,损失函数对它的梯度总是可以写成两部分 $$\begin{eqnarray} \frac{\partial{L}}{\partial{W_{x, y}}} &=& \frac{\partial{L}}{\partial{net_y}} \cdot \frac{\partial{net_y}}{\partial{W_{x,y }}}\\ &=&\frac{\partial{L}}{\partial{net_y}}y_x\\ &\rightarrow& \delta_y \cdot y_x \end{eqnarray}$$
对$\delta_y$进一步拆分,z是y的下一层神经元 $$\begin{eqnarray} \delta_y &=& \frac{\partial{L}}{\partial{net_y}}\\ &=& \frac{\partial{L}}{\partial{y_y}}\cdot \frac{\partial{y_y}}{\partial{net_y}}\\ &=& f^{'}(net_y)\frac{\partial{L}}{\partial{y_y}} \end{eqnarray}$$
而 $$\begin{eqnarray} \frac{\partial{L}}{\partial{y_y}} &=& \sum_z \frac{\partial{L}}{\partial{net_z}}\cdot \frac{\partial{net_z}}{\partial{y_y}}\\ &=& \sum_z \delta_z \cdot W_{y, z} \end{eqnarray}$$
那么有 $$\Delta W_{x, y} = \eta \cdot \delta_y \cdot y_x$$ 而 $$\delta_y = f^{'}(net_y)\sum_z \delta_z\cdot W_{y, z}$$ 这就将每层参数的更新形式定下来了,并且相邻层的关系也给出了。
最后一层网络的$\delta$记为$\delta_n$ $$\begin{eqnarray} \delta_n &=& \frac{\partial{L}}{\partial{net_n}}\\ &=& \frac{\partial{L}}{\partial{y_n}}\cdot \frac{\partial{y_n}}{\partial{net_n}}\\ &=& f^{'}(net_n)\cdot \frac{\partial{L}}{\partial{y_n}} \end{eqnarray}$$ 从$\delta_n$开始可以依次计算其他层的$\delta$。
注意,这里只使用了一个样本,当有多个样本同时训练时(batch),应该如何做?把每个样本计算的$\Delta$加起来作为最终的$\Delta$。因为有激活函数,所以从输出到$\Delta$的变换不是线性的,那么就不能先将结果加起来,在计算最终的$\Delta$,应分别计算每个样本的$\Delta$再求和,矩阵化见下面。
这里的$\delta$和$net_k$都是矩阵,每一行对应一个样本。“$\times$”是矩阵乘法,“$\cdot$”是矩阵点乘。
因为$p_n$包含了指数函数,计算过程中可能会溢出,所以一般采用一些技巧来避免。看下面的变换,参考softmax: $$\begin{eqnarray} p_n &=& \frac{C\cdot e^{y_n}}{C \cdot \sum_x^C e^{y_x}}\\ &=& \frac{e^{y_n + \log C}}{\sum_x^C e^{y_x + \log C}} \end{eqnarray}$$
一般取$\log C = -\max y_n$
对网络的输出求导(参考Derivative of Softmax loss function) $$\frac{\partial{L}}{\partial{y_n}} = \sum_i \frac{\partial{L}}{\partial{p_i}} \cdot \frac{\partial{p_i}}{\partial{y_n}}$$
数学意义上,ReLU在0处没有导数,但为了方便实现,一般0处的导数置为0。参考Neural network backpropagation with RELU。 $$ReLU(x) = max(0, x)\\ ReLU^{'}(x) = \begin{cases} 0, x \le 0\\ 1, x > 0 \end{cases}$$
主要检验在反向传播时每个参数的梯度是否计算正确,梯度的计算方法,除了上面用到的理论计算方法,还有一种极限方式(参考Gradient checking)的定义: $$\frac{\partial{L}}{\partial{W}} \approx \frac{L(W + \epsilon) - L(W - \epsilon)}{2\epsilon}$$
注意W中的参数是分开检验的,检验一个参数时,其他参数保持不变。
一层网络看成并列在一起的多个感知机(如下图)。对于第k层网络,求权重的导数。
注意 多个样本更新weight时取的是$\Delta$的平均值。
bias的更新也是取平均值。
In [ ]: